#include "Buffer.h"
#include <UnitTest++.h>

SUITE(BufferTest) {

    TEST(can_set_data) {
        Buffer buffer("abc");
        char* data = "xyz";
        buffer.assign_raw_data(data);
        string value = buffer.get_string();
        CHECK_EQUAL("xyz", value);
    }

    TEST(has_initial_offset_of_zero) {
        Buffer buffer("");
        CHECK_EQUAL(0U, buffer.get_offset());
    }

    TEST(can_get_offset) {
        Buffer buffer("a");
        buffer.get_char();
        CHECK_EQUAL(1U, buffer.get_offset());
    }

    TEST(can_rewind) {
        Buffer buffer("a");
        buffer.get_char();
        buffer.rewind();
        CHECK_EQUAL(0U, buffer.get_offset());
    }

    TEST(can_get_char) {
        Buffer buffer("a");
        char value = buffer.get_char();
        CHECK_EQUAL('a', value);
    }

    TEST(put_char_moves_forward_by_one_byte) {
        char data[] = {'a'};
        Buffer buffer(data);
        buffer.put_char('z');
        CHECK_EQUAL(1U, buffer.get_offset());
    }

    TEST(can_put_char) {
        char data[] = {'a'};
        Buffer buffer(data);
        buffer.put_char('z');
        buffer.rewind();
        CHECK_EQUAL('z', data[0]);
    }

    TEST(get_short_moves_forward_by_two_bytes) {
        Buffer buffer("ab");
        buffer.get_short();
        CHECK_EQUAL(2U, buffer.get_offset());
    }

    TEST(can_get_short) {
        short value = 12345;
        Buffer buffer((char*)&value);
        short short_value = buffer.get_short();
        CHECK_EQUAL(value, short_value);
    }

    TEST(put_short_moves_forward_by_two_bytes) {
        char data[] = {1, 2};
        Buffer buffer(data);
        buffer.put_short(0);
        CHECK_EQUAL(2U, buffer.get_offset());
    }

    TEST(can_put_short) {
        char data[] = {1, 2};
        Buffer buffer(data);
        buffer.put_short(12345);
        buffer.rewind();
        CHECK_EQUAL(12345, buffer.get_short());
    }

    TEST(get_int_moves_forward_by_four_bytes) {
        Buffer buffer("abcd");
        buffer.get_int();
        CHECK_EQUAL(4U, buffer.get_offset());
    }

    TEST(can_get_int) {
        int value = 12345689;
        Buffer buffer((char*)&value);
        int int_value = buffer.get_int();
        CHECK_EQUAL(value, int_value);
    }

    TEST(put_int_moves_forward_by_four_bytes) {
        char data[] = {1, 2, 3, 4};
        Buffer buffer(data);
        buffer.put_int(0);
        CHECK_EQUAL(4U, buffer.get_offset());
    }

    TEST(can_put_int) {
        char data[] = {1, 2, 3, 4};
        Buffer buffer(data);
        buffer.put_int(123456789);
        buffer.rewind();
        CHECK_EQUAL(123456789, buffer.get_int());
    }

    TEST(get_string_moves_forward_by_length_plus_one_bytes) {
        string s("abc");
        Buffer buffer((char*)s.c_str());
        buffer.get_string();
        CHECK_EQUAL(s.length() + 1, buffer.get_offset());
    }

    TEST(can_get_string) {
        Buffer buffer("abc");
        string value = buffer.get_string();
        CHECK_EQUAL("abc", value);
    }

    TEST(put_string_moves_forward_by_length_plus_one_bytes) {
        char data[] = {1, 2};
        Buffer buffer(data);
        buffer.put_string("a");
        CHECK_EQUAL(2U, buffer.get_offset());
    }

    TEST(can_put_string) {
        char data[] = {1, 2};
        Buffer buffer(data);
        buffer.put_string("a");
        buffer.rewind();
        CHECK_EQUAL("a", buffer.get_string());
    }

    TEST(can_move_offset_forward) {
        Buffer buffer("a");
        buffer.move_offset(+1);
        CHECK_EQUAL(1U, buffer.get_offset());
    }

    TEST(can_move_offset_backward) {
        Buffer buffer("a");
        buffer.get_char();
        buffer.move_offset(-1);
        CHECK_EQUAL(0U, buffer.get_offset());
    }

    TEST(moving_offset_returns_previous_offset) {
        Buffer buffer("a");
        buffer.get_char();
        unsigned int previous_offset = buffer.move_offset(-1);
        CHECK_EQUAL(1U, previous_offset);
    }

    TEST(can_set_offset) {
        Buffer buffer("a");
        buffer.set_offset(1);
        CHECK_EQUAL(1U, buffer.get_offset());
    }

    TEST(setting_offset_returns_previous_offset) {
        Buffer buffer("a");
        buffer.get_char();
        unsigned int previous_offset = buffer.set_offset(0);
        CHECK_EQUAL(1U, previous_offset);
    }
}
